package com.cloud.business.service.sys.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cloud.business.dao.sys.SysRolePermissionMapper;
import com.cloud.business.dao.sys.SysRoleUserMapper;
import com.cloud.business.dao.sys.SysUserMapper;
import com.cloud.business.entity.sys.SysRole;
import com.cloud.business.dao.sys.SysRoleMapper;
import com.cloud.business.entity.sys.SysRolePermission;
import com.cloud.business.entity.sys.SysRoleUser;
import com.cloud.business.model.commonvm.DataCheckFlag;
import com.cloud.business.model.commonvm.DeletePost;
import com.cloud.business.model.commonvm.ResultMsg;
import com.cloud.business.model.sys.sysrolevm.SysRoleQueryModel;
import com.cloud.business.model.sys.sysrolevm.SysRoleVm;
import com.cloud.business.model.sys.sysrolevm.UpdateRoleUsersPost;
import com.cloud.business.service.sys.ISysRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统角色 服务实现类
 * </p>
 *
 * @author dh
 * @since 2020-03-21
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {


    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysRoleUserMapper sysRoleUserMapper;

    @Resource
    private SysRolePermissionMapper sysRolePermissionMapper;


    //region 获取分页列表

    /**
     * 获取分页列表
     *
     * @param sysRoleQueryModel
     * @param page
     * @param msg
     * @throws Exception
     */
    @Override
    public void getListByPage(SysRoleQueryModel sysRoleQueryModel, IPage<SysRoleVm> page, ResultMsg msg) throws Exception {
        QueryWrapper<SysRole> sysRoleQueryWrapper = new QueryWrapper<>();
        sysRoleQueryWrapper.lambda().ne(sysRoleQueryModel.getOperationId() != -1, SysRole::getCode, "SuperAdmin")
                .like(!StringUtils.isEmpty(sysRoleQueryModel.getQueryStr()), SysRole::getName, sysRoleQueryModel.getQueryStr())
                .or().like(!StringUtils.isEmpty(sysRoleQueryModel.getQueryStr()), SysRole::getCode, sysRoleQueryModel.getQueryStr())
                ;

        IPage<SysRole> iPage = new Page<>(page.getCurrent(), page.getSize());

        sysRoleMapper.selectPage(iPage, sysRoleQueryWrapper);

        page.setTotal(iPage.getTotal());

        if (iPage.getRecords().size() > 0) {

            /**
             * 用条件构造器获取角色id集合
             * List<Integer> roleUserIds = new ArrayList<>();
             if (sysRoleQueryModel.getUserId() != null && sysRoleQueryModel.getUserId() != 0) {
             QueryWrapper<SysRoleUser> sysRoleUserQueryWrapper = new QueryWrapper<>();
             sysRoleUserQueryWrapper.lambda()
             .select(SysRoleUser::getRoleId)
             .eq(SysRoleUser::getUserId, sysRoleQueryModel.getUserId());
             List<Object> roleUserIdsObj = sysRoleUserMapper.selectObjs(sysRoleUserQueryWrapper);
             roleUserIdsObj.forEach(roleUser -> {
             roleUserIds.add((Integer.parseInt(roleUser.toString())));
             });
             }*/

            List<Integer> roleIds = sysRoleUserMapper.getRoleIdsByUserId(sysRoleQueryModel.getUserId());
            List<SysRole> sysRoleList = iPage.getRecords();
            List<SysRoleVm> sysRoleVmList = new ArrayList<>();
            sysRoleList.forEach(item -> {
                SysRoleVm sysRoleVm = new SysRoleVm();
                BeanUtils.copyProperties(item, sysRoleVm);
                if (sysRoleQueryModel.getUserId() != null && sysRoleQueryModel.getUserId() != 0) {
                    sysRoleVm.setCheckFlag(roleIds.contains(item.getObjectId()));
                }
                //翻译已经分配了的用户
                List<String> nameList = sysUserMapper.getUserNamesByRoleId(item.getObjectId());
                String userNames = org.apache.commons.lang.StringUtils.join(nameList, "|");
                sysRoleVm.setUserName(userNames);
                sysRoleVmList.add(sysRoleVm);
            });
            page.setRecords(sysRoleVmList);
        }

        msg.setMsg("获取成功");
    }
    //endregion

    //region 创建

    /**
     * 创建
     *
     * @param sysRole
     * @param msg
     * @return
     * @throws Exception
     */
    @Override
    public Integer create(SysRole sysRole, ResultMsg msg) throws Exception {
        Date now = new Date();
        sysRole.setCreateTime(now);
        sysRole.setModificationTime(now);
        if (StringUtils.isEmpty(sysRole.getCode())) {
            throw new Exception("code不能空");
        }

        QueryWrapper<SysRole> sysRoleQueryWrapper = new QueryWrapper<>();
        sysRoleQueryWrapper.lambda().eq(SysRole::getCode, sysRole.getCode());
        SysRole sysRoleOld = sysRoleMapper.selectOne(sysRoleQueryWrapper);

        if (sysRoleOld != null) {
            throw new Exception("code重复");
        }

        int count = sysRoleMapper.insert(sysRole);
        msg.setMsg("创建成功");
        return sysRole.getObjectId();
    }
    //endregion

    //region 更新

    /**
     * 更新
     *
     * @param sysRole
     * @param msg
     * @return
     * @throws Exception
     */
    @Override
    public Integer update(SysRole sysRole, ResultMsg msg) throws Exception {

        if (StringUtils.isEmpty(sysRole.getCode())) {
            throw new Exception("code不能空");
        }

        SysRole sysRoleOld = sysRoleMapper.selectById(sysRole.getObjectId());

        if (!sysRoleOld.getCode().toUpperCase().equals(sysRole.getCode().toUpperCase())) {

            QueryWrapper<SysRole> sysRoleQueryWrapper = new QueryWrapper<>();
            sysRoleQueryWrapper.lambda().eq(SysRole::getCode, sysRole.getCode());
            SysRole sysRoleOldCode = sysRoleMapper.selectOne(sysRoleQueryWrapper);

            if (sysRoleOldCode != null) {
                throw new Exception("code重复");
            }
        }
        Date now = new Date();
        sysRole.setModificationTime(now);
        int count = sysRoleMapper.updateById(sysRole);
        msg.setMsg("更新成功");
        return sysRole.getObjectId();
    }
    //endregion

    //region 获取单条

    /**
     * 获取单条
     *
     * @param operationId
     * @param objectId
     * @param msg
     * @return
     * @throws Exception
     */
    @Override
    public SysRole getById(Integer operationId, Integer objectId, ResultMsg msg) throws Exception {
        SysRole sysRole = sysRoleMapper.selectById(objectId);
        msg.setMsg("获取成功");
        return sysRole;
    }
    //endregion

    //region 批量删除

    /**
     * 批量删除
     *
     * @param deletePost
     * @param msg
     * @return
     * @throws Exception
     */
    @Override
    public int deleteByList(DeletePost deletePost, ResultMsg msg) throws Exception {
        msg.setMsg("删除成功");
        int count = sysRoleMapper.deleteBatchIds(deletePost.getKeyValues());
        //    int count = sysRoleMapper.deleteBatchIds(deletePost.getKeyValues());
        if (count <= 0) {
            throw new Exception("删除失败");
        }

        //删除关联角色用户
        QueryWrapper<SysRoleUser> sysRoleUserQueryWrapper = new QueryWrapper<>();
        sysRoleUserQueryWrapper.lambda().in(SysRoleUser::getRoleId, deletePost.getKeyValues());
        sysRoleUserMapper.delete(sysRoleUserQueryWrapper);
        //删除关联角色权限
        QueryWrapper<SysRolePermission> sysRolePermissionQueryWrapper = new QueryWrapper<>();
        sysRolePermissionQueryWrapper.lambda().in(SysRolePermission::getRoleId, deletePost.getKeyValues());
        sysRolePermissionMapper.delete(sysRolePermissionQueryWrapper);

        return count;
    }
    //endregion

    //region 更新角色用户

    /**
     * 更新角色用户
     *
     * @param updateRoleUsersPost
     * @param msg
     * @return
     * @throws Exception
     */
    @Override
    public Boolean updateRoleUsers(UpdateRoleUsersPost updateRoleUsersPost, ResultMsg msg) throws Exception {
        Date now = new Date();
        QueryWrapper<SysRoleUser> sysRoleUserQueryWrapper = new QueryWrapper<>();
        sysRoleUserQueryWrapper.lambda()
                .eq(SysRoleUser::getRoleId, updateRoleUsersPost.getRoleId());
        List<SysRoleUser> sysRoleUserList = sysRoleUserMapper.selectList(sysRoleUserQueryWrapper);
        List<Integer> alreadyUserIds = sysRoleUserList.stream().map(SysRoleUser::getUserId).collect(Collectors.toList());
        List<DataCheckFlag> dateCheckFlagList = updateRoleUsersPost.getDataChecks();
        if (dateCheckFlagList != null && dateCheckFlagList.size() > 0) {

            List<SysRoleUser> sysRoleUserAddList = new ArrayList<>();
            List<Integer> removeUserIds = new ArrayList<>();

            dateCheckFlagList.forEach(item -> {
                if (item.isCheckFlag() && !alreadyUserIds.contains(item.getObjectId())) {

                    SysRoleUser sysRoleUser = new SysRoleUser() {{
                        setIsDeleted(0);
                        setCreateTime(now);
                        setModificationTime(now);
                        setCreateUserId(updateRoleUsersPost.getOperationId());
                        setModificationUserId(updateRoleUsersPost.getOperationId());
                        setUserId(item.getObjectId());
                        setRoleId(updateRoleUsersPost.getRoleId());
                    }};
                    sysRoleUserAddList.add(sysRoleUser);
                } else if (!item.isCheckFlag() && alreadyUserIds.contains(item.getObjectId())) {
                    SysRoleUser sysRoleUser = sysRoleUserList.stream().filter(o -> o.getUserId().equals(item.getObjectId()))
                            .findAny().orElse(null);
                    if (sysRoleUser != null) {
                        removeUserIds.add(sysRoleUser.getObjectId());
                    }
                }
            });
            if (sysRoleUserAddList.size() > 0) {
                //批量插入到数据库
                sysRoleUserMapper.insertBatch(sysRoleUserAddList);
            }
            if (removeUserIds.size() > 0) {
                sysRoleUserMapper.deleteBatchIds(removeUserIds);
            }
        }

        msg.setMsg("更新成功");
        return true;
    }

    @Override
    public List<Map> getSysRoleCode(Integer operationId, Integer userId, ResultMsg msg) throws Exception {
        List<Map> list = sysRoleMapper.getSysRoleCode(userId);
        msg.setMsg("获取成功");
        return list;
    }
    //endregion

}
